"use strict";

(function() {
	if (!alx.lj.selectionModes) alx.lj.selectionModes = {};
	
	alx.lj.selectionModes.Rect = function (args) {
		alx.lj.inherit(this, alx.lj.selectionModes.ISelectionMode);
		
		var me          = this,
				startPoint  = null,
				lastPoint   = null,
				rect        = null,
				selectables = null,
				hitList     = null,
				prefs       = alx.lj.prefs;
		
		var init = function () {
			var svgArgs = {
				"fill":             prefs.visual.strokeColor(),
				"fill-opacity":     prefs.visual.fillOpacity(),
				"stroke":           prefs.visual.strokeColor(),
				"stroke-width":     prefs.visual.strokeWidth(),
				"stroke-linecap":   prefs.visual.strokeLineCap(),
				"stroke-linejoin":  prefs.visual.strokeLineJoin(),
				"stroke-dasharray": prefs.visual.strokeDashArray(),
				"rx":               prefs.visual.rectRoundedX(),
				"ry":               prefs.visual.rectRoundedY(),
				"shape-rendering":  "crispEdges"
			};

			rect = new alx.svg.Rect(svgArgs);
			args.canvas.append(rect);		
		};
		
		me.toString = function () {
			return "[alx.lj.selectionModes.Rect]";
		};
		
		var clearHitList = function () {
			hitList = [];
		};
				
		var calcArea = function (bounds) {
			return (bounds.right - bounds.left) * (bounds.bottom - bounds.top);
		};
		
		var calcIntersection = function (selectable) {
			var sb = selectable.getBounds();
			var rb = rect.getBounds();
			var rr = {};
			var area = 0;
			
			var ir = {};
			
			if ((sb.left >= rb.left) && (sb.left <= rb.right)) {
				ir.left = sb.left;
			}
			else if ((rb.left >= sb.left) && (rb.left <= sb.right)) {
				ir.left = rb.left;
			}
			
			if ((sb.right >= rb.left) && (sb.right <= rb.right)) {
				ir.right = sb.right;
			}
			else if ((rb.right >= sb.left) && (rb.right <= sb.right)) {
				ir.right = rb.right;
			}
			
			if ((sb.top >= rb.top) && (sb.top <= rb.bottom)) {
				ir.top = sb.top;
			}
			else if ((rb.top >= sb.top) && (rb.top <= sb.bottom)) {
				ir.top = rb.top;
			}
			
			if ((sb.bottom >= rb.top) && (sb.bottom <= rb.bottom)) {
				ir.bottom = sb.bottom;
			}
			else if ((rb.bottom >= sb.top) && (rb.bottom <= sb.bottom)) {
				ir.bottom = rb.bottom;
			}
			
			if (ir.top && ir.right && ir.bottom && ir.left) {
				return ir;
			}
			else {
				return null;
			}
		};
		
		var updateHits = function () {
			var rb,
					ib,
					item,
					hitPercentage,
					selectableArea,
					intersectionArea,
					minHitPercentage,
					selectablesLength,
					intersectionRect;
			
			clearHitList();
			
			rb = rect.getBounds();
			minHitPercentage = prefs.selectionModes.rect.hitPercentageInclusion();
			
			selectablesLength = selectables.length;
			for (var i=0; i < selectablesLength; i++) {
				item = selectables[i];
				ib = item.getBounds();
				
				hitPercentage = 0;
				intersectionRect = rect.intersect(ib);
				
				if (intersectionRect) {
					if (minHitPercentage > 0) {
						selectableArea   = calcArea(ib);
						intersectionArea = calcArea(intersectionRect);
						hitPercentage    = intersectionArea * 100 / selectableArea;
					}
					
					if (hitPercentage >= minHitPercentage) {
						hitList.push(item);
						item.showSelectionRect(args.canvas);
					}
					else {
						item.hideSelectionRect();
					}
				}
				else {
					item.hideSelectionRect();
				}
			}
		};
		
		var clearSelectionRects = function () {
			
		};
		
		// ISelectionMode methods -----------------------------------------
		me.selectionStart = function (pos) {
			startPoint = pos;
			
			rect.setOrigin(pos);
			rect.show();
		};
		
		me.setSelectables = function (s) {
			selectables = s;
		};
		
		me.getHits = function () {
			return hitList;
		};
		
		me.selectionStop = function (x,y) {
			rect.hide();
			clearSelectionRects();
		};
		
		me.selectionCancel = function (x,y) {
			
		};
		
		me.handlePosition = function (pos) {
			lastPoint = pos;
			rect.setSecond(pos);
			updateHits();
		};
		
		// ---------------------------------------------------------------
		init();
	};
})();